package sharing

import (
	"fmt"
	"log"
	"sync"
)

var (
	ErrInvalidPool = fmt.Errorf("goroutine pool is invalid")
)

// Pool goroutine池
type Pool struct {
	wg sync.WaitGroup
	ch chan struct{}
}

// NewPool new一个协程池
// size 协程池的size
func NewPool(size uint) *Pool {
	return &Pool{
		wg: sync.WaitGroup{},
		ch: make(chan struct{}, size),
	}
}

// Add channel加入struct，满阻塞，不满则完成信号量+1
func (g *Pool) Add() {
	if g == nil {
		log.Panic(ErrInvalidPool)
	}
	g.ch <- struct{}{}
	g.wg.Add(1)
}

// Done 任务结束，channel释放struct，信号量-1
func (g *Pool) Done() {
	if g == nil {
		log.Panic(ErrInvalidPool)
	}
	<-g.ch
	g.wg.Done()
}

// Wait 等待信号量归零
func (g *Pool) Wait() {
	if g == nil {
		log.Panic(ErrInvalidPool)
	}
	g.wg.Wait()
}
